<template>
  <div class="file">
    <el-tabs v-model="activeName">
      <el-tab-pane label="论文上传" name="upload">
        <el-row>
          <el-col :span="2">
            <div style="height: 1px;"></div>
          </el-col>
          <el-col :span="20">
            <div>
              <el-card header="批量上传">
                <el-steps :active="stepsActive" finish-status="success" align-center style="margin-bottom: 20px;">
                  <el-step title="上传EXCEL论文表格"></el-step>
                  <el-step title="上传PDF文件"></el-step>
                </el-steps>
                
                <!-- 步骤1：上传EXCEL论文表格 -->
                <div v-show="stepsActive === 0" style="display: flex;justify-content: space-around;">
                    <el-button type="primary" @click="showDialog3 = true">下载excel模板</el-button>
                    <el-upload
                      class="upload-demo"
                      action=""
                      :multiple="false"
                      :http-request="httpRequest"
                      accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
                    >
                      <el-button size="small" type="primary" :loading="loadingUpload">选择论文excel表格</el-button>
                      <div slot="tip" class="el-upload__tip">只能上传 xls / xlsx 文件</div>
                    </el-upload>
                    <el-progress v-if="showProgress" :percentage="progressPercent" :stroke-width="2"></el-progress>
                </div>

                <!-- 步骤2：上传PDF文件 -->
                <div v-show="stepsActive >= 1" style="display: flex;justify-content: space-around;">
                  <el-upload
                    class="upload-demo"
                    ref="fileInput2"
                    action=""
                    :auto-upload="false"
                    accept="application/pdf"
                    multiple
                  >
                    <el-button slot="trigger" size="small" type="primary">选取PDF文件</el-button>
                    <div slot="tip" class="el-upload__tip">只能上传pdf文件,且大小不超过100MB</div>
                  </el-upload>
                  <el-button style="height: 40px;" type="primary" @click="handleUploadPdf" :loading="loadingUpload">上 传</el-button>
                </div>

                <el-divider />
                <div style="margin: 20px 0;display: flex;justify-content: space-around;">
                  <el-button size="small" @click="pre" :disabled="stepsActive <= 0">上一步</el-button>
                  <el-button size="small" @click="next" :disabled="stepsActive >= 1 || !paperUploadSuccess">下一步</el-button>
                </div>

                <div>
                  <el-alert
                    title="以下论文的文件名重复, 重复的论文将不会被上传，请正常选择需要上传的PDF文件，系统会自动过滤掉文件名重复的文件。"
                    type="warning"
                    show-icon
                    :closable="false"
                    style="margin-bottom: 10px;"
                    v-if="repeatedError.length > 0"
                  ></el-alert>
                  <el-alert
                    v-for="(error, index) in repeatedError" :key="index"
                    type="error"
                    show-icon
                    :closable="false"
                    style="margin-bottom: 10px;"
                  >
                    <span slot="title">{{ error.title }}：<strong>{{ error.message }}</strong></span>
                  </el-alert>
                </div>

                <div>
                  <el-alert
                    title="以下文件上传出错，请重新上传！"
                    type="warning"
                    show-icon
                    :closable="false"
                    style="margin-bottom: 10px;"
                    v-if="uploadErrorList.length > 0"
                  >
                  </el-alert>
                  <el-alert
                    v-for="(error, index) in uploadErrorList" :key="index"
                    :closable="false"
                    show-icon
                    type="error"
                    style="margin-bottom: 10px;"
                  >
                    <span slot="title">{{ error.name }}：<strong>{{ error.message }}</strong></span>
                  </el-alert>
                </div>

              </el-card>
            </div>
          </el-col>
          <el-col :span="2">
            <div style="height: 1px;"></div>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="2">
            <div style="height: 1px;"></div>
          </el-col>
          <el-col :span="20">
            <div style="padding-top: 50px;">
              <el-card header="单篇上传">
                <el-form :model="paper" label-width="100px">
                  <el-form-item label="标题">
                    <el-input v-model="paper.title" placeholder="论文标题"></el-input>
                  </el-form-item>
                  <el-form-item label="简介">
                    <el-input v-model="paper.summary" placeholder="论文简介" type="textarea" size="medium" :rows="5">
                    </el-input>
                  </el-form-item>
                  <el-form-item label="PDF文件">
                    <input type="file" ref="fileInput" accept="application/pdf" />
                    <el-alert
                      :closable="false"
                      style="margin-bottom: 10px;"
                      title="为了安全，我们会自动修改您上传的PDF文件名"
                      type="info">
                    </el-alert>
                  </el-form-item>
                  <el-form-item label="发表日期">
                    <el-date-picker
                      v-model="paper.publishedTime"
                      type="month"
                      placeholder="选择日期"
                      :editable="false"
                      :picker-options="pickerOptions"
                    >
                    </el-date-picker>
                  </el-form-item>
                  <el-form-item label="关键字">
                    <el-tag
                      :key="index"
                      v-for="(keyword, index) in paper.keywords"
                      closable
                      :disable-transitions="false"
                      @close="handleCloseByKeyword(keyword)">
                      {{keyword}}
                    </el-tag>
                    <el-input
                      class="input-new-tag"
                      v-if="inputVisibleByKeyword"
                      v-model="inputKeyword"
                      ref="saveTagInputByKeyword"
                      size="small"
                      @keyup.enter.native="handleInputConfirmByKeyword"
                      @blur="handleInputConfirmByKeyword"
                    >
                    </el-input>
                    <el-button v-else class="button-new-tag" size="small" @click="showInputByKeyword">添加关键字</el-button>
                  </el-form-item>
                  <el-form-item label="作者">
                    <el-tag
                      :key="index"
                      v-for="(author, index) in paper.authers"
                      closable
                      :disable-transitions="false"
                      @close="handleCloseByAuthor(author)">
                      {{author}}
                    </el-tag>
                    <el-input
                      class="input-new-tag"
                      v-if="inputVisibleByAuthor"
                      v-model="inputAuthor"
                      ref="saveTagInputByAuthor"
                      size="small"
                      @keyup.enter.native="handleInputConfirmByAuthor"
                      @blur="handleInputConfirmByAuthor"
                    >
                    </el-input>
                    <el-button v-else class="button-new-tag" size="small" @click="showInputByAuthor">添加作者</el-button>
                  </el-form-item>
                  <el-form-item>
                    <el-button @click="clearForm">清除表单</el-button>
                    <el-button type="primary" @click="updateFileNameAndUpload" :loading="loadingUpload">开始上传</el-button>
                  </el-form-item>
                </el-form>
              </el-card>
            </div>
          </el-col>
          <el-col :span="2">
            <div style="height: 1px;"></div>
          </el-col>
        </el-row>
      </el-tab-pane>
    </el-tabs>
    <el-dialog title="您要上传多少篇论文？" :visible.sync="showDialog3">
      <el-input-number v-model="fileNameNumber" :min="1" :max="100" label="数量" name="inputNumber"></el-input-number>
      <template slot="footer">
        <el-button type="primary" @click="handleGetFileName" :loading="loadingUpload">下载模板</el-button>
      </template>
    </el-dialog>
    <copyright class="bottom-layer" />
  </div>
</template>

<script>
import excel from '../libs/excel'
import { formatDate, guid, getToken } from '../libs/tools'
import { put } from '../api/v1/paperManagement'
import { token } from '../api/v1/uniquelyIdentifies'
import { upload, getAll as getAllPdf } from '../api/v1/paperPdf'
export default {
  name: 'Upload',
  data() {
    return {
      progressPercent: 0,
      showProgress: false,
      showDialog3: false,
      activeName: 'upload',
      paper: {
        title: "",
        authers: [],
        publishedTime: Date.now(),
        keywords: [],
        summary: "",
        fileName: ''
      },
      pickerOptions: {
        disabledDate(time) {
          return time.getTime() > Date.now();
        }
      },
      inputVisibleByKeyword: false,
      inputKeyword: '',
      inputVisibleByAuthor: false,
      inputAuthor: '',
      loadingUpload: false,
      tokenArray: [],
      fileNameNumber: 1,
      stepsActive: 0,
      uploadErrorList: [],
      repeatedError: [],
      paperUploadSuccess: false
    }
  },
  methods: {
    clearForm() {
      this.paper = {title:'',authers: [],publishedTime: Date.now(),keywords: [],summary: '',fileName: ''}
    },
    pre() {
      if(this.stepsActive > 0) {
        this.stepsActive = 0
      }
    },
    next() {
      if (this.stepsActive < 2 && this.paperUploadSuccess) {
        this.stepsActive = 1
      }
    },
    handleGetFileName() {
      this.loadingUpload = true
      token(this.fileNameNumber).then(res => {
        this.tokenArray = []
        this.tokenArray = res.data
        this.handleDownloadExcelTemplate()
      }).catch(e => {
        this.loadingUpload = false
        this.$message.error('获取失败!')
      })
    },
    async updateFileNameAndUpload (name) {
      const fileInput = this.$refs.fileInput
      if(fileInput.files.length === 0) {
        this.$message.error('请选择文件')
      } else if (fileInput.files[0].type !== 'application/pdf') {
        this.$message.error('您选择的文件不是PDF文件，请选择PDF文件进行上传！')
      } else if (fileInput.files[0].size > 100 * 1024 * 1024) {
        this.$message.error('您选择的文件超过了最大大小100MB！')
      } else {
        this.loadingInstance = this.$loading.service({text:'正在上传...'})
        let tokenStr
        await token(1).then(res => {
          if(res.data && Array.isArray(res.data) && res.data.length > 0) {
            tokenStr = res.data[0] + '.pdf'
          }
        }).catch(e => {
          console.log(e)
        })
        if(!tokenStr) {
          this.$message.error('服务器获取文件名失败！')
          return
        }
        const file = fileInput.files[0]
        const newFile = new File([file], tokenStr, { type: 'application/pdf' })
        const formData = new FormData()
        formData.append(tokenStr, newFile)
        console.log(formData.get(tokenStr))
        upload(formData).then(res => {
          this.handleUpload(tokenStr)
        }).catch(e => {
          // this.$message.error('上传PDF文件失败!')
          this.$notify({
            title: '上传结果',
            message: '上传PDF文件失败!',
            type: 'error',
            duration: 0
          })
          this.loadingInstance.close()
          console.log(e)
        })
      }
    },
    async handleUploadPdf() {
      const fileInput = this.$refs.fileInput2
      const len = fileInput.uploadFiles.length
      if(len === 0) {
        this.$message.error('请选择文件')
      } else {
        this.uploadErrorList = []
        for (let index = 0; index < len; index++) {
          const file = fileInput.uploadFiles[index]
          if(file.size > 100 * 1024 * 1024) {
            this.uploadErrorList.push({ name: file.name, message: '大小超过100MB' })
          } else if (file.raw.type !== 'application/pdf') {
            this.uploadErrorList.push({ name: file.name, message: '文件类型错误，不是PDF格式的文件' })
          } else if (this.repeatedError.findIndex(item => item.fileName === file.name) !== -1) {
            // 文件名重复了，不需要上传这个文件
            this.uploadErrorList.push({ name: file.name, message: '文件名重复' })
          } else {
            this.loadingInstance = this.$loading.service({text: `文件正在上传...(${index+1}/${len})`})
            const formData = new FormData()
            const newFile = new File([file.raw], file.name, { type: 'application/pdf' })
            formData.append(file.name, newFile)
            await upload(formData).then(res => {
              console.log(res)
            }).catch(e => {
              this.uploadErrorList.push({ name: file.name, message: '未知原因' })
            })
            this.loadingInstance.close()
            console.log(index)
          }
        }
        this.loadingInstance.close()
        this.$notify({
          title: '上传结果',
          message: '上传成功！',
          type: 'success',
          duration: 0
        })
        this.stepsActive = 2
        this.$router.push('/')
      }
    },
    /**
     * @description 导出excel模板文件
     */
    handleDownloadExcelTemplate() {
      const tokenArray = [...this.tokenArray]
      let data = []
      for (let index = 0; index < tokenArray.length; index++) {
        if(index === 0) {
          data.push({ title: '标题', authers: '(用逗号隔开)作者1,作者2,作者3', publishedTime: '', keywords: '(用逗号隔开)关键字1,关键字2,关键字3', summary: '简介', fileName: tokenArray[index] + '.pdf' })
        } else {
          data.push({ title: '', authers: '', publishedTime: '', keywords: '', summary: '', fileName: tokenArray[index] + '.pdf' })
        }
      }
      excel.export_array_to_excel({
        title: ['标题', '作者', '发表日期', '关键字', '文件名', '简介'],
        key: ['title', 'authers', 'publishedTime', 'keywords', 'fileName', 'summary'],
        data,
        // autoWidth: true,
        filename: '论文上传模板_' + Date.now(),
        // 设置 excel 单元格列的宽度，0 - 5列
        cols: [{ wch: 40 }, { wch: 40 }, { wch: 20 }, { wch: 40 }, { wch: 45 }, { wch: 100 }]
      })
      this.tokenArray = []
      this.loadingUpload = false
      this.showDialog3 = false
    },
    /**
     * @description 上传单篇论文，不需要excel
     */
    handleUpload(name) {
      console.log(name)
      const paper = Object.assign({}, this.paper)
      if(!paper.title) {
        this.$message.error('标题不能为空')
        return
      } else if (!paper.publishedTime) {
        this.$message.error('发布时间不能为空')
        return
      } else if (!paper.summary) {
        this.$message.error('简介不能为空')
        return
      }
      paper.fileName = name
      paper.publishedTime = new Date(paper.publishedTime)
      put([paper]).then(res => {
        this.loadingInstance.close()
        this.clearForm()
        this.$notify({
          title: '上传结果',
          message: '上传成功！',
          type: 'success',
          duration: 0
        })
      }).catch(e => {
        console.log(e)
        this.loadingInstance.close()
        this.$message.error('上传失败!')
        this.$notify({
          title: '上传结果',
          message: '上传失败!',
          type: 'error',
          duration: 0
        })
      })
    },
    /**
     * @description 上传多篇论文，需要excel
     */
    async handleUploadMulti(papers) {

      // 获取服务器已存在的文件名
      let pdfNames = []
      await getAllPdf(1, 10000).then(res => {
        if(res.data && res.data.results && Array.isArray(res.data.results)) {
          pdfNames = res.data.results.map(pdf => pdf.name ? pdf.name : '')
        }
      }).catch(e => {
        console.error(e)
      })
      console.log(pdfNames)
      this.repeatedError = []
      const ectypePapers = JSON.parse(JSON.stringify(papers))
      papers.forEach((paper, index) => {
        // 需要上传的论文的文件名已经存在
        if(pdfNames.indexOf(paper.fileName) !== -1) {
          console.log(paper.title)
          this.repeatedError.push({ title: paper.title, message: '该论文的文件名已经存在于服务器，请重新上传该论文。', fileName: paper.fileName })
          ectypePapers.splice(ectypePapers.findIndex((item) => item.fileName === paper.fileName), 1)
        }
      })
      if(ectypePapers.length === 0) {
        this.repeatedError.unshift({ title: '', message: '所有文件都上传失败。', fileName: '' })
        this.loadingUpload = false
        return
      }
      put(ectypePapers).then(res => {
        this.loadingUpload = false
        this.paperUploadSuccess = true
        this.next()
      }).catch(e => {
        this.loadingUpload = false
        // this.$message.error('上传论文失败!')
        this.$notify({
          title: '上传结果',
          message: '上传论文失败!',
          type: 'error',
          duration: 0
        })
        console.log(e)
      })
    },
    // 读取文件
    readFile (file) {
      const reader = new FileReader()
      reader.readAsArrayBuffer(file)
      reader.onloadstart = e => {
        this.showProgress = true
        this.loadingUpload = true
      }
      reader.onprogress = e => {
        this.progressPercent = Math.round(e.loaded / e.total * 100)
      }
      reader.onerror = e => {
        this.$message.error('文件读取出错')
      }
      reader.onload = e => {
        const data = e.target.result
        let { results } = excel.read(data, { type: 'array', cellDates: true })
        let papers = []
        papers = results.map(item => {
          const authers = item['作者'] && (item['作者'] + '').replace(/，/g, ',').split(',') || []
          const keywords = item['关键字'] && (item['关键字'] + '').replace(/，/g, ',').split(',') || []
          authers.forEach((auther, inx) => {
            authers[inx] = auther.trim()
          })
          keywords.forEach((keyword, inx) => {
            keywords[inx] = keyword.trim()
          })
          return {
            authers,
            keywords,
            publishedTime: new Date(item['发表日期']),
            fileName: item['文件名'] && (item['文件名'] + '').trim(),
            title: item['标题'] && (item['标题'] + '').trim(),
            summary: item['简介'] && (item['简介'] + '').trim()
          }
        })
        this.handleUploadMulti(papers)
      }
    },
    httpRequest({ file }) {
      this.showProgress = true
      this.progressPercent = 0
      const fileExt = file.name.split('.').pop().toLocaleLowerCase()
      if (fileExt === 'xlsx' || fileExt === 'xls') {
        this.readFile(file)
      } else {
        this.$message.error('文件类型错误：文件：' + file.name + '不是EXCEL文件，请选择后缀为.xlsx或者.xls的EXCEL文件。')
      }
    },
    handleCloseByKeyword(keyword) {
      this.paper.keywords.splice(this.paper.keywords.indexOf(keyword), 1);
    },
    showInputByKeyword() {
      this.inputVisibleByKeyword = true;
      this.$nextTick(_ => {
        this.$refs.saveTagInputByKeyword.$refs.input.focus();
      });
    },
    handleInputConfirmByKeyword() {
      let inputKeyword = this.inputKeyword;
      if (inputKeyword) {
        this.paper.keywords.push(inputKeyword);
      }
      this.inputVisibleByKeyword = false;
      this.inputKeyword = '';
    },
    handleCloseByAuthor(author) {
      this.paper.authers.splice(this.paper.authers.indexOf(author), 1);
    },
    showInputByAuthor() {
      this.inputVisibleByAuthor = true;
      this.$nextTick(_ => {
        this.$refs.saveTagInputByAuthor.$refs.input.focus();
      });
    },
    handleInputConfirmByAuthor() {
      let inputAuthor = this.inputAuthor;
      if (inputAuthor) {
        this.paper.authers.push(inputAuthor);
      }
      this.inputVisibleByAuthor = false;
      this.inputAuthor = '';
    }
  },
}
</script>

<style scoped>
.file {
  position: relative;
  min-height: calc(100vh - 120px);
}

.input {
  margin-top: 20px;
}

.el-tag + .el-tag {
  margin-left: 10px;
}
.button-new-tag {
  margin-left: 10px;
  height: 32px;
  line-height: 30px;
  padding-top: 0;
  padding-bottom: 0;
}
.input-new-tag {
  width: 90px;
  margin-left: 10px;
  vertical-align: bottom;
}

ol {
  padding: 0;
}

ol > li {
  margin: 10px;
}
</style>